﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using SegIdenMovil.Entidad;
using SegIdenMovil.DataAccess;
using System.Data;

namespace SegIdenMovil.Datos
{
    public class DAOrdenCompra
    {
        #region --- Constantes ---
        private string CAB_CODOC = "CODOC";
        private string CAB_PRECIOIF = "PRECIOIF";
        private string CAB_CODPROVEEDOR = "CODPROVEEDOR";
        private string CAB_IDENTIFICACION = "IDENTIFICACION";
        private string CAB_RAZONSOCIAL = "RAZONSOCIAL";
        private string CAB_CODUSUARIO = "CODUSUARIO";
        private string CAB_NOMBRESYAPELLIDOS = "NOMBRESYAPELLIDOS";
        private string CAB_ORIGEN = "ORIGEN";
        private string CAB_ESTADO = "ESTADO";
        private string CAB_FECHAREGISTRO = "FECHAREGISTRO";
        private string CAB_CODMONEDA = "CODMONEDA";
        
        private string DET_CODOC = "CODOC";
        private string DET_NROLINEA = "NROLINEA";
        private string DET_CODCLIENTE = "CODCLIENTE";
        private string DET_NRODOCUMENTO = "NRODOCUMENTO";
        private string DET_RAZONSOCIAL = "RAZONSOCIAL";
        private string DET_CODTIENDA = "CODTIENDA";
        private string DET_NOMBRE = "NOMBRE";
        private string DET_CODPRODUCTO = "CODPRODUCTO";
        private string DET_CODPRODUCTOPROVEEDOR = "CODPRODUCTOPROVEEDOR";
        private string DET_DESCRIPCION = "DESCRIPCION";
        private string DET_CANTIDAD = "CANTIDAD";
        private string DET_CANTIDADRECIBIDA = "CANTIDADRECIBIDA";
        private string DET_PRECIOEW = "PRECIOEW";
        private string DET_VENTADIRECTA = "VENTADIRECTA";
        private string DET_ESTADO = "ESTADO";
        private string DET_COMPONENTES = "COMPONENTES";

        private string PARAM_CAB_CODOC = "@CODOC";
        private string PARAM_CAB_PRECIOIF = "@PRECIOIF";
        private string PARAM_CAB_CODPROVEEDOR = "@CODPROVEEDOR";
        private string PARAM_CAB_IDENTIFICACION = "@IDENTIFICACION";
        private string PARAM_CAB_RAZONSOCIAL = "@RAZONSOCIAL";
        private string PARAM_CAB_CODUSUARIO = "@CODUSUARIO";
        private string PARAM_CAB_NOMBRESYAPELLIDOS = "@NOMBRESYAPELLIDOS";
        private string PARAM_CAB_ORIGEN = "@ORIGEN";
        private string PARAM_CAB_ESTADO = "@ESTADO";
        private string PARAM_CAB_FECHAREGISTRO = "@FECHAREGISTRO";
        private string PARAM_CAB_CODMONEDA = "@CODMONEDA";

        private string PARAM_DET_CODOC = "@CODOC";
        private string PARAM_DET_NROLINEA = "@NROLINEA";
        private string PARAM_DET_CODCLIENTE = "@CODCLIENTE";
        private string PARAM_DET_NRODOCUMENTO = "@NRODOCUMENTO";
        private string PARAM_DET_RAZONSOCIAL = "@RAZONSOCIAL";
        private string PARAM_DET_CODTIENDA = "@CODTIENDA";
        private string PARAM_DET_NOMBRE = "@NOMBRE";
        private string PARAM_DET_CODPRODUCTO = "@CODPRODUCTO";
        private string PARAM_DET_CODPRODUCTOPROVEEDOR = "@CODPRODUCTOPROVEEDOR";
        private string PARAM_DET_DESCRIPCION = "@DESCRIPCION";
        private string PARAM_DET_CANTIDAD = "@CANTIDAD";
        private string PARAM_DET_CANTIDADRECIBIDA = "@CANTIDADRECIBIDA";
        private string PARAM_DET_PRECIOEW = "@PRECIOEW";
        private string PARAM_DET_VENTADIRECTA = "@VENTADIRECTA";
        private string PARAM_DET_ESTADO = "@ESTADO";
        private string PARAM_DET_COMPONENTES = "@COMPONENTES";
        #endregion

        #region --- Metodos Propios ---
        public bool guardar(OrdenCompra ordenCompra)
        {
            int resultado = 0;

            StringBuilder sentenciaCabeceraSQL = null;
            StringBuilder sentenciaDetalleSQL = null;

            sentenciaCabeceraSQL = new StringBuilder();
            sentenciaCabeceraSQL.Append("INSERT INTO ordencompra ( ");
            sentenciaCabeceraSQL.Append("CODOC, PRECIOIF, CODMONEDA, CODPROVEEDOR, IDENTIFICACION, ");
            sentenciaCabeceraSQL.Append("RAZONSOCIAL, CODUSUARIO, NOMBRESYAPELLIDOS, ORIGEN, ESTADO, ");
            sentenciaCabeceraSQL.Append("FECHAREGISTRO) ");
            sentenciaCabeceraSQL.Append("VALUES(@CODOC, @PRECIOIF, @CODMONEDA, @CODPROVEEDOR, @IDENTIFICACION, ");
            sentenciaCabeceraSQL.Append("@RAZONSOCIAL, @CODUSUARIO, @NOMBRESYAPELLIDOS, @ORIGEN, @ESTADO, ");
            sentenciaCabeceraSQL.Append("@FECHAREGISTRO) ");

            sentenciaDetalleSQL = new StringBuilder();
            sentenciaDetalleSQL.Append("INSERT INTO det_ordencompra ( ");
            sentenciaDetalleSQL.Append("CODOC, NROLINEA, CODCLIENTE, NRODOCUMENTO, RAZONSOCIAL, ");
            sentenciaDetalleSQL.Append("CODTIENDA, NOMBRE, CODPRODUCTO, CODPRODUCTOPROVEEDOR, DESCRIPCION, ");
            sentenciaDetalleSQL.Append("CANTIDAD, CANTIDADRECIBIDA, PRECIOEW, VENTADIRECTA, ESTADO, ");
            sentenciaDetalleSQL.Append("COMPONENTES) ");
            sentenciaDetalleSQL.Append("VALUES(@CODOC, @NROLINEA, @CODCLIENTE, @NRODOCUMENTO, @RAZONSOCIAL, ");
            sentenciaDetalleSQL.Append("@CODTIENDA, @NOMBRE, @CODPRODUCTO, @CODPRODUCTOPROVEEDOR, @DESCRIPCION, ");
            sentenciaDetalleSQL.Append("@CANTIDAD, @CANTIDADRECIBIDA, @PRECIOEW, @VENTADIRECTA, @ESTADO, ");
            sentenciaDetalleSQL.Append("@COMPONENTES)");

            // Carga de datos obtenido de la BD
            using (Database db = new Database())
            {
                using (IDbTransaction transa = db.iniciarTransaccionSQLite())
                {

                    #region --- Registro OrdenCompra ---
                    db.TextoSQL = sentenciaCabeceraSQL.ToString();
                    db.agregarParametro(PARAM_CAB_CODOC, DbType.Int32, ParameterDirection.Input, ordenCompra.codOC);
                    db.agregarParametro(PARAM_CAB_PRECIOIF, DbType.String, ParameterDirection.Input, ordenCompra.precioInternalFreight);
                    db.agregarParametro(PARAM_CAB_CODMONEDA, DbType.Int32, ParameterDirection.Input, ordenCompra.moneda.codigo);
                    db.agregarParametro(PARAM_CAB_CODPROVEEDOR, DbType.Int32, ParameterDirection.Input, ordenCompra.proveedor.codProveedor);
                    db.agregarParametro(PARAM_CAB_IDENTIFICACION, DbType.String, ParameterDirection.Input, ordenCompra.proveedor.identificacion);
                    db.agregarParametro(PARAM_CAB_RAZONSOCIAL, DbType.String, ParameterDirection.Input, ordenCompra.proveedor.razonSocial);
                    db.agregarParametro(PARAM_CAB_CODUSUARIO, DbType.Int32, ParameterDirection.Input, ordenCompra.usuario.codUsuario);
                    db.agregarParametro(PARAM_CAB_NOMBRESYAPELLIDOS, DbType.String, ParameterDirection.Input, ordenCompra.usuario.nombresyApellidos);
                    db.agregarParametro(PARAM_CAB_ORIGEN, DbType.String, ParameterDirection.Input, ordenCompra.origen);
                    db.agregarParametro(PARAM_CAB_ESTADO, DbType.String, ParameterDirection.Input, ordenCompra.estado);
                    db.agregarParametro(PARAM_CAB_FECHAREGISTRO, DbType.String, ParameterDirection.Input, ordenCompra.fechaRegistro);

                    resultado += db.ejecutar();
                    #endregion

                    #region --- Registro Detalle OrdenCompra ---
                    db.TextoSQL = sentenciaDetalleSQL.ToString();

                    db.agregarParametro(PARAM_DET_CODOC, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_NROLINEA, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CODCLIENTE, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_NRODOCUMENTO, DbType.String, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_RAZONSOCIAL, DbType.String, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CODTIENDA, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_NOMBRE, DbType.String, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CODPRODUCTO, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CODPRODUCTOPROVEEDOR, DbType.String, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_DESCRIPCION, DbType.String, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CANTIDAD, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CANTIDADRECIBIDA, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_PRECIOEW, DbType.Decimal, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_VENTADIRECTA, DbType.String, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_ESTADO, DbType.String, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_COMPONENTES, DbType.String, ParameterDirection.Input);

                    foreach (LineaOrdenCompra lineaOrdenCompra in ordenCompra.listaLineaOrdenCompra.lista)
                    {
                        db.obtenerParametro(PARAM_DET_CODOC).Value = lineaOrdenCompra.codOC;
                        db.obtenerParametro(PARAM_DET_NROLINEA).Value = lineaOrdenCompra.numeroLinea;
                        db.obtenerParametro(PARAM_DET_CODCLIENTE).Value = lineaOrdenCompra.cliente.codCliente;
                        db.obtenerParametro(PARAM_DET_NRODOCUMENTO).Value = lineaOrdenCompra.cliente.nroDocumento ?? string.Empty;
                        db.obtenerParametro(PARAM_DET_RAZONSOCIAL).Value = lineaOrdenCompra.cliente.razonSocial ?? string.Empty;
                        db.obtenerParametro(PARAM_DET_CODTIENDA).Value = lineaOrdenCompra.tienda.codigo;
                        db.obtenerParametro(PARAM_DET_NOMBRE).Value = lineaOrdenCompra.tienda.nombre ?? string.Empty;
                        db.obtenerParametro(PARAM_DET_CODPRODUCTO).Value = lineaOrdenCompra.producto.codigo;
                        db.obtenerParametro(PARAM_DET_CODPRODUCTOPROVEEDOR).Value = lineaOrdenCompra.producto.codProductoProveedor;
                        db.obtenerParametro(PARAM_DET_DESCRIPCION).Value = lineaOrdenCompra.producto.descripcion;
                        db.obtenerParametro(PARAM_DET_CANTIDAD).Value = lineaOrdenCompra.cantidad;
                        db.obtenerParametro(PARAM_DET_CANTIDADRECIBIDA).Value = lineaOrdenCompra.cantidadRecibida;
                        db.obtenerParametro(PARAM_DET_PRECIOEW).Value = lineaOrdenCompra.precioExworks;
                        db.obtenerParametro(PARAM_DET_VENTADIRECTA).Value = lineaOrdenCompra.ventaDirecta;
                        db.obtenerParametro(PARAM_DET_ESTADO).Value = lineaOrdenCompra.estado;
                        db.obtenerParametro(PARAM_DET_COMPONENTES).Value = lineaOrdenCompra.producto.componentes;

                        resultado += db.ejecutar();
                    }
                    #endregion

                    transa.Commit();
                }
            }

            return resultado>0;
        }

        public bool actualizar(OrdenCompra ordenCompra)
        {
            int resultado = 0;

            StringBuilder sentenciaCabeceraSQL = null;
            StringBuilder sentenciaDetalleSQL = null;

            sentenciaCabeceraSQL = new StringBuilder();
            sentenciaCabeceraSQL.Append("UPDATE ordencompra SET ");
            sentenciaCabeceraSQL.Append("ESTADO = @ESTADO ");
            sentenciaCabeceraSQL.Append("WHERE CODOC = @CODOC");

            sentenciaDetalleSQL = new StringBuilder();
            sentenciaDetalleSQL.Append("UPDATE det_ordencompra SET ");
            sentenciaDetalleSQL.Append("CANTIDADRECIBIDA = @CANTIDADRECIBIDA, ");
            sentenciaDetalleSQL.Append("ESTADO = @ESTADO ");
            sentenciaDetalleSQL.Append("WHERE CODOC = @CODOC ");
            sentenciaDetalleSQL.Append("AND CODPRODUCTO = @CODPRODUCTO");

            // Carga de datos obtenido de la BD
            using (Database db = new Database())
            {
                using (IDbTransaction transa = db.iniciarTransaccionSQLite())
                {

                    #region --- Actualizar OrdenCompra ---
                    db.TextoSQL = sentenciaCabeceraSQL.ToString();
                    db.agregarParametro(PARAM_CAB_CODOC, DbType.Int32, ParameterDirection.Input, ordenCompra.codOC);
                    db.agregarParametro(PARAM_CAB_ESTADO, DbType.String, ParameterDirection.Input, ordenCompra.estado);

                    resultado += db.ejecutar();
                    #endregion

                    #region --- Actualizar Detalle OrdenCompra ---
                    db.TextoSQL = sentenciaDetalleSQL.ToString();

                    db.agregarParametro(PARAM_DET_CODOC, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CODPRODUCTO, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_CANTIDADRECIBIDA, DbType.Int32, ParameterDirection.Input);
                    db.agregarParametro(PARAM_DET_ESTADO, DbType.String, ParameterDirection.Input);

                    foreach (LineaOrdenCompra lineaOrdenCompra in ordenCompra.listaLineaOrdenCompra.lista)
                    {
                        db.obtenerParametro(PARAM_DET_CODOC).Value = lineaOrdenCompra.codOC;
                        db.obtenerParametro(PARAM_DET_CODPRODUCTO).Value = lineaOrdenCompra.producto.codigo;
                        db.obtenerParametro(PARAM_DET_CANTIDADRECIBIDA).Value = lineaOrdenCompra.cantidadRecibida;
                        db.obtenerParametro(PARAM_DET_ESTADO).Value = lineaOrdenCompra.estado;

                        resultado += db.ejecutar();
                    }
                    #endregion

                    transa.Commit();
                }
            }

            return resultado > 0;
        }

        public OrdenCompra obtenerOrdenCompra(OrdenCompra ordenCompra)
        {
            OrdenCompra ordenCompraResultado = null;
            StringBuilder sentenciaSQL = null;
            DataSet dsDatos = null;
            DataTable tbOrdenCompra = null;
            DataTable tbDetalleOrdenCompra = null;

            sentenciaSQL = new StringBuilder();
            sentenciaSQL.Append("SELECT CODOC, PRECIOIF, CODMONEDA, ");
            sentenciaSQL.Append("CODPROVEEDOR, IDENTIFICACION, RAZONSOCIAL, ");
            sentenciaSQL.Append("CODUSUARIO, NOMBRESYAPELLIDOS, ");
            sentenciaSQL.Append("ORIGEN, ESTADO, FECHAREGISTRO ");
            sentenciaSQL.Append("FROM ordencompra ");
            sentenciaSQL.Append("WHERE CODOC = " + ordenCompra.codOC + ";");

            sentenciaSQL.Append("SELECT CODOC, NROLINEA, ");
            sentenciaSQL.Append("CODCLIENTE, NRODOCUMENTO, RAZONSOCIAL, ");
            sentenciaSQL.Append("CODTIENDA, NOMBRE, ");
            sentenciaSQL.Append("CODPRODUCTO, CODPRODUCTOPROVEEDOR, DESCRIPCION, ");
            sentenciaSQL.Append("CANTIDAD, CANTIDADRECIBIDA, ");
            sentenciaSQL.Append("PRECIOEW, VENTADIRECTA, ");
            sentenciaSQL.Append("ESTADO, COMPONENTES ");
            sentenciaSQL.Append("FROM det_ordencompra ");
            sentenciaSQL.Append("WHERE CODOC = " + ordenCompra.codOC);

            // Carga de datos obtenido de la BD
            using (Database db = new Database())
            {
                db.TextoSQL = sentenciaSQL.ToString();

                IDataAdapter dataAdapter = db.obtenerDataAdapter();
                dsDatos = new DataSet();
                dataAdapter.Fill(dsDatos);

                tbOrdenCompra = dsDatos.Tables[0];
                tbDetalleOrdenCompra = dsDatos.Tables[1];

                if (tbOrdenCompra.Rows.Count > 0)
                {
                    ordenCompraResultado = generarEntidadOrdenCompra(tbOrdenCompra.Rows[0]);

                    ordenCompraResultado.listaLineaOrdenCompra = new ListaLineaOrdenCompra();
                    foreach (DataRow fila in tbDetalleOrdenCompra.Rows)
                    {
                        ordenCompraResultado.listaLineaOrdenCompra.add(generarEntidadLineaOrdenCompra(fila));
                    }
                }
            }

            return ordenCompraResultado;
        }

        private OrdenCompra generarEntidadOrdenCompra(DataRow fila)
        {
            OrdenCompra ordenCompra = new OrdenCompra();

            ordenCompra.codOC = fila[CAB_CODOC].ToString();
            ordenCompra.precioInternalFreight = fila[CAB_PRECIOIF].ToString();

            ordenCompra.moneda = new Moneda();
            ordenCompra.moneda.codigo = fila[CAB_CODMONEDA].ToString();

            ordenCompra.proveedor = new Proveedor();
            ordenCompra.proveedor.codProveedor = fila[CAB_CODPROVEEDOR].ToString();
            ordenCompra.proveedor.identificacion = fila[CAB_IDENTIFICACION].ToString();
            ordenCompra.proveedor.razonSocial = fila[CAB_RAZONSOCIAL].ToString();

            ordenCompra.usuario = new Usuario();
            ordenCompra.usuario.codUsuario = fila[CAB_CODUSUARIO].ToString();
            ordenCompra.usuario.nombresyApellidos = fila[CAB_NOMBRESYAPELLIDOS].ToString();

            ordenCompra.origen = fila[CAB_ORIGEN].ToString();
            ordenCompra.estado = fila[CAB_ESTADO].ToString();

            ordenCompra.fechaRegistro = fila[CAB_FECHAREGISTRO].ToString();

            return ordenCompra;
        }

        private LineaOrdenCompra generarEntidadLineaOrdenCompra(DataRow fila)
        {
            LineaOrdenCompra lineaOrdenCompra = new LineaOrdenCompra();

            lineaOrdenCompra.codOC = fila[DET_CODOC].ToString();
            lineaOrdenCompra.numeroLinea = fila[DET_NROLINEA].ToString();

            lineaOrdenCompra.cliente = new Cliente();
            lineaOrdenCompra.cliente.codCliente = fila[DET_CODCLIENTE].ToString();
            lineaOrdenCompra.cliente.nroDocumento = fila[DET_NRODOCUMENTO].ToString();
            lineaOrdenCompra.cliente.razonSocial = fila[DET_RAZONSOCIAL].ToString();

            lineaOrdenCompra.tienda = new Tienda();
            lineaOrdenCompra.tienda.codigo = fila[DET_CODTIENDA].ToString();
            lineaOrdenCompra.tienda.nombre = fila[DET_NOMBRE].ToString();

            lineaOrdenCompra.producto = new Producto();
            lineaOrdenCompra.producto.codigo = fila[DET_CODPRODUCTO].ToString();
            lineaOrdenCompra.producto.codProductoProveedor = fila[DET_CODPRODUCTOPROVEEDOR].ToString();
            lineaOrdenCompra.producto.descripcion = fila[DET_DESCRIPCION].ToString();
            lineaOrdenCompra.producto.componentes = fila[DET_COMPONENTES].ToString();

            lineaOrdenCompra.cantidad = fila[DET_CANTIDAD].ToString();
            lineaOrdenCompra.cantidadRecibida = fila[DET_CANTIDADRECIBIDA].ToString();

            lineaOrdenCompra.precioExworks = Convert.ToDouble(fila[DET_PRECIOEW]);
            lineaOrdenCompra.ventaDirecta = fila[DET_VENTADIRECTA].ToString();
            lineaOrdenCompra.estado = fila[DET_ESTADO].ToString();

            return lineaOrdenCompra;
        }
        #endregion
    }
}
